import os
import subprocess
import sys
import difflib
from pathlib import Path
from colorama import init, Fore, Style

# 初始化colorama
init()

# 设置测试目录
TEST_DIR = Path(os.path.dirname(os.path.abspath(__file__))) / "tests"
PROJECT_ROOT = Path(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

# 全局变量控制输出详细程度
QUIET_MODE = False

def run_test(input_file):
    """运行单个测试文件并比较结果"""
    # 构建输出文件路径
    output_file = input_file.with_suffix(".out")
    
    # 检查输出文件是否存在
    if not output_file.exists():
        print(f"{Fore.RED}错误: 找不到输出文件 {output_file}{Style.RESET_ALL}")
        return False
    
    # 运行编译器
    try:
        result = subprocess.run(
            ["cargo", "run", "--", str(input_file)],
            cwd=PROJECT_ROOT,
            capture_output=True,
            text=True,
            check=False
        )
        
        # 获取编译器输出并过滤掉cargo的编译信息
        stderr_lines = result.stderr.strip().splitlines()
        # 过滤掉cargo的编译信息行
        filtered_lines = []
        for line in stderr_lines:
            # 跳过cargo编译信息和运行信息
            if line.startswith('Finished') or line.startswith('     Running'):
                continue
            filtered_lines.append(line)
        
        compiler_output = '\n'.join(filtered_lines).strip()
        
        # 读取预期输出
        with open(output_file, 'r') as f:
            expected_output = f.read().strip()
        
        # 比较输出
        if compiler_output == expected_output:
            if not QUIET_MODE:
                print(f"{Fore.GREEN}✓ 测试通过: {input_file.name}{Style.RESET_ALL}")
            return True
        else:
            print(f"{Fore.RED}✗ 测试失败: {input_file.name}{Style.RESET_ALL}")
            
            # 生成差异报告
            diff = difflib.unified_diff(
                expected_output.splitlines(),
                compiler_output.splitlines(),
                fromfile=str(output_file),
                tofile="编译器输出",
                lineterm=""
            )
            
            print(f"\n{Fore.YELLOW}差异:{Style.RESET_ALL}")
            for line in diff:
                if line.startswith('+'):
                    print(f"{Fore.GREEN}{line}{Style.RESET_ALL}")
                elif line.startswith('-'):
                    print(f"{Fore.RED}{line}{Style.RESET_ALL}")
                elif line.startswith('@'):
                    print(f"{Fore.CYAN}{line}{Style.RESET_ALL}")
                else:
                    print(line)
            print()
            
            return False
    except Exception as e:
        print(f"{Fore.RED}运行测试时出错 {input_file.name}: {e}{Style.RESET_ALL}")
        return False

def run_all_tests():
    """运行所有测试文件"""
    input_files = sorted(TEST_DIR.glob("*.in"))
    
    if not input_files:
        print(f"{Fore.RED}错误: 在 {TEST_DIR} 中找不到测试文件{Style.RESET_ALL}")
        return
    
    print(f"{Fore.CYAN}找到 {len(input_files)} 个测试文件{Style.RESET_ALL}")
    
    passed = 0
    failed = 0
    failed_tests = []
    
    for input_file in input_files:
        if run_test(input_file):
            passed += 1
        else:
            failed += 1
            failed_tests.append(input_file.name)
    
    # 打印摘要
    print(f"\n{Fore.CYAN}测试摘要:{Style.RESET_ALL}")
    print(f"总计: {passed + failed} 个测试")
    print(f"通过: {Fore.GREEN}{passed}{Style.RESET_ALL}")
    print(f"失败: {Fore.RED if failed > 0 else Fore.GREEN}{failed}{Style.RESET_ALL}")
    
    if failed > 0:
        print(f"\n{Fore.RED}失败的测试:{Style.RESET_ALL}")
        for test in failed_tests:
            print(f"  - {test}")
    else:
        print(f"\n{Fore.GREEN}所有测试都通过了!{Style.RESET_ALL}")

def print_help():
    """打印帮助信息"""
    print(f"{Fore.CYAN}用法:{Style.RESET_ALL}")
    print(f"  python {sys.argv[0]} [选项] [测试文件]")
    print(f"\n{Fore.CYAN}选项:{Style.RESET_ALL}")
    print(f"  -h, --help     显示此帮助信息")
    print(f"  -q, --quiet    安静模式，只显示失败的测试")

if __name__ == "__main__":
    # 解析命令行参数
    quiet_mode = False
    test_file = None
    
    args = sys.argv[1:]
    i = 0
    while i < len(args):
        arg = args[i]
        if arg in ["-h", "--help"]:
            print_help()
            sys.exit(0)
        elif arg in ["-q", "--quiet"]:
            quiet_mode = True
            i += 1
        else:
            # 假设这是测试文件名
            test_file = Path(arg)
            i += 1
    
    # 设置全局变量控制输出详细程度
    QUIET_MODE = quiet_mode
    
    # 如果提供了特定的测试文件，则只运行该文件
    if test_file:
        if not test_file.is_absolute():
            test_file = TEST_DIR / test_file
        run_test(test_file)
    else:
        # 否则运行所有测试
        run_all_tests()